library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;

library work;
 use work.router_pack.all;

-------------------------------------------------------------------------------
entity spa4 is
-------------------------------------------------------------------------------
port( 
      RESET   : in  std_logic;
 
      -- MUTEX input i/f: --
      R       : in  std_logic_vector(num_of_sl_con-1 downto 0);
      GATE    : in  std_logic;
      
      -- MUTEX output i/f: --
      G       : out std_logic_vector(num_of_sl_con-1 downto 0);
       
      -- Data Latches: --
      L       : out std_logic_vector(num_of_sl_con-1 downto 0)
);           
-------------------------------------------------------------------------------
end spa4 ;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
architecture spa4_arch of spa4 is
-------------------------------------------------------------------------------
component mutex
port( 
      -- MUTEX input i/f: --
      R1      : in  std_logic;
      R2      : in  std_logic;

      -- MUTEX output i/f: --
      G1      : out std_logic;
      G2      : out std_logic
);           
end component;

component srlab2
port(
      RN                             :	in    std_logic;
      SN                             :	in    std_logic;
      Q                              :	out   std_logic;
      QN                             :	out   std_logic
);
end component;

component c_element
port( 
      -- Input i/f: --
      A     : in  std_logic;
      B     : in  std_logic;

      -- output i/f: --
      Q     : out std_logic
);           
end component;

signal g1_arr : std_logic_vector(3 downto 0);
signal g2_arr : std_logic_vector(3 downto 0);
signal g_and_arr : std_logic_vector(3 downto 0);

signal r_or_not, r_from_latch : std_logic;  

signal pri_mod_out : std_logic_vector(3 downto 0);

signal g_or_not : std_logic; 

begin

r_or_not <= not ( R(0) or R(1) or R(2) or R(3) );

u_srlab2: srlab2 
port map( 
      RN    => g_or_not,
      SN    => r_or_not,

      Q     => r_from_latch, -- lock
      QN    => open
);   

sl_data_latch_gen: for i in 0 to (num_of_sl_con-1) generate

 u_mutex_spa: mutex
 port map( 

      R1      => r_from_latch, -- lock
      R2      => R(i),

      G1      => g1_arr(i),
      G2      => g2_arr(i)
 );

 g_and_arr(i) <= g2_arr(i) and r_from_latch;  -- req + lock

 u_c_element1: c_element
 port map( 
      A     => g2_arr(i),
      B     => pri_mod_out(i),

      Q     => G(i)
 ); 

end generate;

-- Latch is open when request are valid and locked.
L <= not g_and_arr;

--g_and_arr(1) <= g2_arr(1) and r_from_latch;
--g_and_arr(2) <= g2_arr(2) and r_from_latch;
--g_and_arr(3) <= g2_arr(3) and r_from_latch;

prior_module_proc: process( g1_arr, g_and_arr )
 variable g_arr : std_logic_vector(7 downto 0);
begin

 --       Lock0       Req0             Lock1       Req1          Lock2       Req2            Lock3       Req3 
 g_arr := g1_arr(0) & g_and_arr(0) & g1_arr(1) & g_and_arr(1) & g1_arr(2) & g_and_arr(2) & g1_arr(3) & g_and_arr(3); 

 

 case g_arr is
  when "10101001" | 
       "10100101" | 
       "10011001" | 
       "10010101" | 
       "01101001" | 
       "01100101" | 
       "01011001" | 
       "01010101" =>  -- there is 4th SL request.
    pri_mod_out <= "1000"; -- highest priority (SL=3).

  when "10100110" | 
       "10010110" |
       "01100110" |
       "01010110" =>
    pri_mod_out <= "0100"; -- middle priority (SL=2).

  when "10011010" |
       "01011010" =>
    pri_mod_out <= "0010";

  when "01101010" =>  -- request from the lowest priority and no other requests from higher priorities.
    pri_mod_out <= "0001";

  when others=>
    pri_mod_out <= (others=>'0');
 end case;

end process;

g_or_not <= not (GATE or RESET);

-------------------------------------------------------------------------------
end spa4_arch;
-------------------------------------------------------------------------------                 

   
-------------------------------------------------------------------------------
configuration  spa4_cfg  of spa4 is
-------------------------------------------------------------------------------
   for spa4_arch
   end for;
-------------------------------------------------------------------------------
end  spa4_cfg;              
-------------------------------------------------------------------------------
                 
